//
// Created by Zhangwj on 2023/9/18.
//

#ifndef COMPILE_TASK2_LEXER_H
#define COMPILE_TASK2_LEXER_H


#include <string>
#include <map>

enum class LexType {
    IDENFR,
    INTCON,
    STRCON,
    MAINTK,
    CONSTTK,
    INTTK,
    BREAKTK,
    CONTINUETK,
    IFTK,
    ELSETK,
    NOT,
    AND,
    OR,
    FORTK,
    GETINTTK,
    PRINTFTK,
    RETURNTK,
    PLUS,
    MINU,
    VOIDTK,
    MULT,
    DIV,
    MOD,
    LSS,
    LEQ,
    GRE,
    GEQ,
    EQL,
    NEQ,
    ASSIGN,
    SEMICN,
    COMMA,
    LPARENT,
    RPARENT,
    LBRACK,
    RBRACK,
    LBRACE,
    RBRACE,
    LEXER_ERROR,
    LEXER_END,
};

class Lexer {
public:
    explicit Lexer(std::string source);

    std::tuple<LexType, std::string> next();

    char getNextChar();

    void tokenAppend(char c);

    char tokenAppendAndGetNext(char c);

    void backwardCurPos();

    void moveToNBC();

private:
    std::string source;
    std::string::size_type curPos;
    std::string token;
    unsigned int lineNum;
};


#endif //COMPILE_TASK2_LEXER_H
